﻿using System;
using System.Collections.Generic;
using System.Text;

namespace C11_Ex02_1
{
    public class ComputerAI
    {
        public enum ComputerType
        {
            Easy,
            Normal,
            Hard
        }

        private List<BoardPosition> m_ListOfCellsRememberedByComputer;
        private BoardPosition m_ComputerLastMove;
        private ComputerType m_ComputerType;
        private Random RandomNumberGenerator = new Random();
        private bool m_IsComputerFirstMove;

        public ComputerAI(ComputerType i_ChoosenComputerType)
        {
            m_ListOfCellsRememberedByComputer = new List<BoardPosition>();
            m_ComputerLastMove = null;
            m_ComputerType = i_ChoosenComputerType;
            m_IsComputerFirstMove = true;
        }

        public BoardPosition CalculateComputerNextMove(CardsTable io_Board)
        {
            BoardPosition ReturnValue = null;
            BoardPosition[] AvailableCells = io_Board.CreateHiddenCellsArray();
            bool FoundSimilarSecondCell = false;

            if (m_ComputerType == ComputerType.Easy)
            {
                ReturnValue = getRandomMovePosition(AvailableCells);
            }
            else
            {
                if (m_IsComputerFirstMove)
                {
                    removeCellsPositionsThatWereRevealed(io_Board);
                    if (AvailableCells.Length != 0)
                    {
                        if (m_ComputerType == ComputerType.Hard)
                        {
                            ReturnValue = findTwoSimilarCellsInComputerRememberList(io_Board);
                        }
                        else
                        {
                            ReturnValue = getRandomMovePosition(AvailableCells);
                        }
                    }

                    m_IsComputerFirstMove = false;
                    if (ReturnValue == null)
                    {
                        ReturnValue = getRandomMovePosition(AvailableCells);
                    }
                    m_ComputerLastMove = ReturnValue;
                }
                else
                {
                    FoundSimilarSecondCell = false;
                    foreach (BoardPosition KnownCell in m_ListOfCellsRememberedByComputer)
                    {
                        if (io_Board.CompareCellsValues(m_ComputerLastMove,KnownCell) && 
                            (!m_ComputerLastMove.ComparePositions(KnownCell)))
                        {
                            ReturnValue = KnownCell;
                            m_ListOfCellsRememberedByComputer.Remove(KnownCell);
                            FoundSimilarSecondCell = true;
                            break;
                        }
                    }

                    if (!FoundSimilarSecondCell)
                    {
                        ReturnValue = getRandomMovePosition(AvailableCells);
                    }

                    m_IsComputerFirstMove = true;
                    m_ComputerLastMove = null;
                }
            }

            return ReturnValue;
        }

        private BoardPosition getRandomMovePosition(BoardPosition[] io_AvalibleCells)
        {
            BoardPosition ComputerRandomMove = null;
            int RandomNumber = RandomNumberGenerator.Next(0, io_AvalibleCells.Length - 1);

            ComputerRandomMove = io_AvalibleCells[RandomNumber];
            if (!doesListOfCellsContainsCellInTheSamePosition(m_ListOfCellsRememberedByComputer, ComputerRandomMove))
            {
                m_ListOfCellsRememberedByComputer.Add(ComputerRandomMove);
            }
            
            m_ComputerLastMove = ComputerRandomMove;
            
            return ComputerRandomMove;
        }

        private bool doesListOfCellsContainsCellInTheSamePosition(List<BoardPosition> i_ListOfCellsRememberedByComputer, BoardPosition i_ComputerRandomMove)
        {
            bool ReturnValue = false;

            for (int q = 0; q < (i_ListOfCellsRememberedByComputer.Count - 1); ++q)
            {
                if (i_ListOfCellsRememberedByComputer[q].ComparePositions(i_ComputerRandomMove))
                {
                    ReturnValue = true;
                    break;
                }
            }

            return ReturnValue;
        }

        private BoardPosition findTwoSimilarCellsInComputerRememberList(CardsTable i_Board)
        {
            BoardPosition ReturnValue = null;
            bool WasCellFound = false;

            for (int i = 0; (i < m_ListOfCellsRememberedByComputer.Count - 1) && (!WasCellFound) ; i++)
            {
                for (int j = i+1; j < m_ListOfCellsRememberedByComputer.Count; j++)
                {
                    if (i_Board.CompareCellsValues(m_ListOfCellsRememberedByComputer[i], m_ListOfCellsRememberedByComputer[j]))
                    {
                        ReturnValue = m_ListOfCellsRememberedByComputer[i];
                        m_ListOfCellsRememberedByComputer.RemoveAt(i);
                        WasCellFound = true;
                        break;
                    }
                }
            }

            return ReturnValue;
        }

        private void removeCellsPositionsThatWereRevealed(CardsTable i_Board)
        {
            for (int i = 0; i < m_ListOfCellsRememberedByComputer.Count; i++)
            {
                if (i_Board.IsCellRevealed(m_ListOfCellsRememberedByComputer[i]))
                {
                    m_ListOfCellsRememberedByComputer.RemoveAt(i);
                    i--;
                }
            }
        }
    }
}

